package cn.tangwei.user.service.impl;

import cn.tangwei.basic.exception.BusinessException;
import cn.tangwei.basic.utils.SmsUtils;
import cn.tangwei.basic.utils.StrUtils;
import cn.tangwei.user.constants.UserConstants;
import cn.tangwei.user.domain.User;
import cn.tangwei.user.mapper.UserMapper;
import cn.tangwei.user.service.IVerifyCodeSercive;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeSerciveImpl implements IVerifyCodeSercive {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void sSmsCode(Map<String, String> map) {
        String phone = map.get("phone");
        String type = map.get("type");
        // 1.校验手机号不能为空
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)){// 为空
            throw new BusinessException("参数不能为空");
        }
        String businessKey = "";
        if ("register".equals(type)){// 注册逻辑
            // 1.2手机号是否被注册了 方法：查询user表
            User user = userMapper.loadByPhone(phone);
            if(user != null){// 不等于null就代表数据库表已经存在电话
                throw new BusinessException("该用户已经注册，请直接登录");
            }
            businessKey =  UserConstants.BUSINESS_REGISTER_PREFIX + phone;
        }else if ("binder".equals(type)){// 绑定逻辑
            businessKey = UserConstants.BUSINESS_BINDER_PREFIX + phone;
        }
        if(StringUtils.hasLength(businessKey)){
            sendCode(businessKey);
        }
    }

    /**
     *  真正发送验证码的逻辑
     * @param businessKey
     */
    public void sendCode(String businessKey){
        // 2.判断验证码是否有效（3分钟），从redis中能否拿到key
        Object codeTmp = redisTemplate.opsForValue().get(businessKey);
        String code = "";
        if(codeTmp != null){// 表示拿到了redis
            // 2.1 如果拿到了需要判断是否过了一分钟重发时间，
            String timeTpm = codeTmp.toString().split(":")[1];// 从：截取成字字符串数组，拿到下标为一的串phomephome
            if(System.currentTimeMillis()-Long.valueOf(timeTpm)<=1*60*1000){// 表示没有过一分钟
                // 如果没有过重发时间,报错：请勿重发获取验证码
                throw new BusinessException("请勿重复发送验证码");
            }else {
                //  如果过了，使用上次的验证码
                code = codeTmp.toString().split(":")[0];
            }
        }else {
            // 2.2 如果拿不到,直接生成新的验证码
            code = StrUtils.getComplexRandomString(4);
        }
        // 3.存储redis 设置3分钟过期
        redisTemplate.opsForValue().set(businessKey,
                code+":"+System.currentTimeMillis(), 3, TimeUnit.MINUTES);// TimeUnit.MINUTES表示三分钟后期
        // 4.发送短信通知客人 验证码是：9527 请在3分钟内使用
//        SmsUtils.send(phone, "验证码为："+code+" ；请再三分钟内使用");
        System.out.println("验证码为："+code+" ；请再三分钟内使用");

    }

}
